<?php
class DropdownList extends DataObject implements PermissionProvider {
    private static $singular_name = "Dropdown List";
    private static $plural_name = "Dropdown Lists";
    
    private static $db = array(
        'Code' => 'Varchar',
        'Title' => 'Varchar(250)',
        'Active' => 'Boolean',
        'Sort' => 'Int',
        'Locale' => 'Varchar'
    );

    private static $api_access = array('view' => array(
        'Code',
        'Title'
    ));

    private static $searchable_fields = array(
        'Code',
        'Title',
        'Active',
        'Locale'
    );

    private static $summary_fields = array(
        'Code',
        'Title',
        'Active.Nice',
        'Locale'
    );

    private static $default_sort = 'ClassName, Code, Sort';

    private static $defaults = array('Active' => true);
	
	public function fieldLabels($includerelations = true) {
		$labels = parent::fieldLabels($includerelations);
		
		$labels['Code'] = _t('DropdownList.CODE', 'Code');
		$labels['Title'] = _t('DropdownList.TITLE', 'Title');
		$labels['Active'] = _t('DropdownList.IS_ACTIVE', 'Is Active?');
		$labels['Active.Nice'] = _t('DropdownList.IS_ACTIVE', 'Is Active?');
		$labels['Locale'] = _t('DropdownList.LOCALE', 'Locale');
		
		return $labels;	
	}

    /**
     * Set custom validation for dropdown list form
     *
     * @return Validator
     */
    function getCMSValidator() {
        return DropdownList_Validator::create();
    }

    /**
     * Set not allow to edit default code & title
     *
     * @return FieldSet
     */
    function getCMSFields() {
        $fields = parent::getCMSFields();

        if($this->exists()) {
            $fields->makeFieldReadonly('Code');
			$fields->dataFieldByName('Code')->setIncludeHiddenField(true);
        }
		
		if(class_exists('Translatable')){
			$locale_list = array();
			$allowed_locale = Translatable::get_allowed_locales();
			$locale = i18n::get_common_locales();
			foreach($allowed_locale as $code){
				if(isset($locale[$code])){
					$locale_list[$code] = $locale[$code];
				}
			}
		}
		else {
			$locale_list = i18n::get_common_locales();
		}
		$fields->replaceField('Locale', DropdownField::create('Locale', $this->fieldLabel('Locale'), $locale_list));
		
		$fields->removeByName('Sort');

        return $fields;
    }

    function map($locale = null) {
    	$sourceClass = $this->class;
		if(!$locale) $locale = i18n::get_locale();
        return $sourceClass::get()->filter('Locale', $locale)->filter('Active', 1)->map('Code', 'Title');
    }

    function getDropdownField($name, $title) {
        return DropdownField::create($name, $title)->setSource($this->map());
    }

	function canView($member = false) {
        $extended = $this->extendedCan(__FUNCTION__, $member);
        if($extended !== null) {
            return $extended;
        }
        return Permission::check(sprintf('VIEW_%s', $this->class));
    }

    function canEdit($member = false) {
        $extended = $this->extendedCan(__FUNCTION__, $member);
        if($extended !== null) {
            return $extended;
        }
        return Permission::check(sprintf('EDIT_%s', $this->class));
    }

    function canDelete($member = false) {
        $extended = $this->extendedCan(__FUNCTION__, $member);
        if($extended !== null) {
            return $extended;
        }
        return Permission::check(sprintf('DELETE_%s', $this->class));
    }

    function canCreate($member = false) {
        $extended = $this->extendedCan(__FUNCTION__, $member);
        if($extended !== null) {
            return $extended;
        }
        return Permission::check(sprintf('CREATE_%s', $this->class));
    }

    public function providePermissions() {
    	if($this->class == 'DropdownList') return array();
		
        return array(
            sprintf('VIEW_%s', $this->class) => array(
                'name' => _t('DropdownList.PERMISSION_VIEW', 'Allow view access right'),
                'category' => $this->i18n_singular_name()
            ),
            sprintf('EDIT_%s', $this->class) => array(
                'name' => _t('DropdownList.PERMISSION_EDIT', 'Allow edit access right'),
                'category' => $this->i18n_singular_name()
            ),
            sprintf('DELETE_%s', $this->class) => array(
                'name' => _t('DropdownList.PERMISSION_DELETE', 'Allow delete access right'),
                'category' => $this->i18n_singular_name()
            ),
            sprintf('CREATE_%s', $this->class) => array(
                'name' => _t('DropdownList.PERMISSION_CREATE', 'Allow create access right'),
                'category' => $this->i18n_singular_name()
            )
        );
    }
}

class DropdownList_Validator extends RequiredFields {
    protected $customRequired = array(
        'Code',
        'Title'
    );

    /**
     * Constructor
     */
    public function __construct() {
        $required = func_get_args();
        if(isset($required[0]) && is_array($required[0])) {
            $required = $required[0];
        }
        $required = array_merge($required, $this->customRequired);

        parent::__construct($required);
    }

    /**
     * Check if the submitted list data is valid (server-side)
     *
     * @param array $data Submitted data
     * @return bool Returns TRUE if the submitted data is valid, otherwise
     *              FALSE.
     */
    function php($data) {
        $valid = parent::php($data);

		$record = $this->form->getRecord();

        if(!$record->exists()) {
            $sourceClass = $record->ClassName;
			$obj = $sourceClass::get()->filter('Code', $data['Code'])->filter('Locale', $data['Locale']);
	
	        if($obj->count()) {
	            $this->validationError('Code', _t('DropdownList.DUPLICATE_CODE', 'Sorry, this code already exists'), 'validation');
	            $valid = false;
	        }
		}

        // Execute the validators on the extensions
        if($this->extension_instances) {
            foreach($this->extension_instances as $extension) {
                if(method_exists($extension, 'hasMethod') && $extension->hasMethod('updatePHP')) {
                    $valid &= $extension->updatePHP($data, $this->form);
                }
            }
        }

        return $valid;
    }
}

class StatusList extends DropdownList {
    private static $singular_name = "Status List";
    private static $plural_name = "Status Lists";
    
    private static $default_records = array(
        array(
            'Code' => 'Active',
            'Title' => 'Active',
            'Sort' => 10,
            'Locale' => 'en_US'
        ),
        array(
            'Code' => 'Inactive',
            'Title' => 'Inactive',
            'Sort' => 20,
            'Locale' => 'en_US'
        ),
        array(
            'Code' => 'Suspend',
            'Title' => 'Suspend',
            'Sort' => 30,
            'Locale' => 'en_US'
        ),
        array(
            'Code' => 'Active',
            'Title' => '活跃',
            'Sort' => 40,
            'Locale' => 'zh_CN'
        ),
        array(
            'Code' => 'Inactive',
            'Title' => '不活跃',
            'Sort' => 50,
            'Locale' => 'zh_CN'
        ),
        array(
            'Code' => 'Suspend',
            'Title' => '暂停服务',
            'Sort' => 60,
            'Locale' => 'zh_CN'
        )
    );

    private static $default_status = 'Active';

    /**
     *
     * @param status code
     */
    static function set_default_status_code($code) {
        Config::inst()->update('StatusList', 'default_status', $code);
    }

    /**
     *
     * @return code
     */
    static function get_default_status_code() {
        return Config::inst()->get('StatusList', 'default_status');
    }

    /**
     *
     * @param Code
     * @return Title
     */
    static function get_title_by_code($code, $locale = null) {
    	if(!$locale) $locale = i18n::get_locale();
        if($status = StatusList::get()->filter('Active', 1)->filter('Locale', $locale)->find('Code', $code)) {
            return $status->Title;
        }
		return $code;
    }
}

?>
